<template>
  <view class="tn-scroll-list-class tn-scroll-list">
    <scroll-view
      class="tn-scroll-list__scroll-view"
      scroll-x
      :upper-threshold="0"
      :lower-threshold="0"
      @scroll="scrollHandler"
      @scrolltoupper="scrollToUpperHandler"
      @scrolltolower="scrollToLowerHandler"
    >
      <view class="tn-scroll-list__scroll-view__content">
        <slot></slot>
      </view>
    </scroll-view>

    <!-- 指示器-->
    <view v-if="indicator" class="tn-scroll-list__indicator" :style="[indicatorStyle]">
      <view class="tn-scroll-list__indicator__line" :style="[lineStyle]">
        <view class="tn-scroll-list__indicator__line__bar" :style="[barStyle]"></view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'tn-scroll-list',
  props: {
    // 是否显示指示器
    indicator: {
      type: Boolean,
      default: true,
    },
    // 指示器整体宽度
    indicatorWidth: {
      type: [String, Number],
      default: 50,
    },
    // 指示器滑块的宽度
    indicatorBarWidth: {
      type: [String, Number],
      default: 20,
    },
    // 指示器颜色
    indicatorColor: {
      type: String,
      default: '#E6E6E6',
    },
    // 指示器激活时颜色
    indicatorActiveColor: {
      type: String,
      default: '#0079fe',
    },
    // 自定义指示器样式
    indicatorStyle: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  computed: {
    // 指示器滑块样式
    barStyle() {
      let style = {};
      // 获取滑动距离的比值
      // 滑块当前移动距离与总需滑动距离(指示器的总宽度减去滑块宽度)的比值 = scroll-view的滚动距离与目标滚动距离(scroll-view的实际宽度减去包裹元素的宽度)之比
      const scrollLeft = this.scrollInfo.scrollLeft,
        scrollWidth = this.scrollInfo.scrollWidth,
        barAllMoveWidth = uni.upx2px(this.indicatorWidth) - uni.upx2px(this.indicatorBarWidth);
      const x = (scrollLeft / (scrollWidth - this.scrollWidth)) * barAllMoveWidth;
      style.transform = `translateX(${x}px)`;
      // 设置滑块的宽度和背景颜色
      style.width = `${this.indicatorBarWidth}rpx`;
      style.backgroundColor = this.indicatorActiveColor;
      return style;
    },
    // 指示器整体样式
    lineStyle() {
      let style = {};
      style.width = `${this.indicatorWidth}rpx`;
      style.backgroundColor = this.indicatorColor;
      return style;
    },
  },
  data() {
    return {
      // 滑动时滑块信息
      scrollInfo: {
        scrollLeft: 0,
        scrollWidth: 0,
      },
      // 滑动区域的宽度
      scrollWidth: 0,
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.init();
    });
  },
  methods: {
    // 初始化
    init() {
      this.getComponentWidth();
    },
    // 处理滚动事件
    scrollHandler(event) {
      this.scrollInfo = event.detail;
    },
    // 滚动到最左边触发事件
    scrollToUpperHandler() {
      this.$emit('left');
      this.scrollInfo.scrollLeft = 0;
    },
    // 滚动到最右边触发事件
    scrollToLowerHandler() {
      this.$emit('right');
      // this.scrollInfo.scrollLeft = uni.upx2px(this.indicatorWidth) - uni.upx2px(this.indicatorBarWidth)
    },
    // 获取组件的宽度
    getComponentWidth() {
      this._tGetRect('.tn-scroll-list').then((res) => {
        if (!res) {
          setTimeout(() => {
            this.getComponentWidth();
          }, 10);
          return;
        }
        this.scrollWidth = res.width;
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.tn-scroll-list {
  padding-bottom: 20rpx;

  &__scroll-view {
    display: flex;
    flex-direction: row;

    &__content {
      display: flex;
      flex-direction: row;
    }
  }

  &__indicator {
    display: flex;
    flex-direction: row;
    justify-content: center;
    margin-top: 10rpx;

    &__line {
      width: 120rpx;
      height: 8rpx;
      border-radius: 200rpx;
      overflow: hidden;

      &__bar {
        width: 40rpx;
        height: 8rpx;
        border-radius: 200rpx;
      }
    }
  }
}
</style>
